package com.angel.shiro;

import org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

/**
 * 基于URL的权限判断过滤器<p>
 * 我们自动根据URL产生所谓的权限字符串，这一项在Shiro示例中是写在配置文件里面的，默认认为权限不可动态配置<p>
 * URL举例：/User/create.do?***=***  -->权限字符串：/User/create.
 *
 * @author Rabit
 */
public class URLPermissionsFilter extends PermissionsAuthorizationFilter {

    /**
     * @param mappedValue 指的是在声明url时指定的权限字符串，如/User/create=perms[User:create].我们要动态产生这个权限字符串，所以这个配置对我们没用
     */

    @Override
    public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws IOException {
        return super.isAccessAllowed(request, response, buildPermissions(request));
    }

    /**
     * 根据请求URL产生权限字符串，这里只产生，而比对的事交给Realm
     *
     * @param request 请求的request
     * @return 处理过的权限字符串集合
     */
    protected String[] buildPermissions(ServletRequest request) {
        String[] perms = new String[1];
        HttpServletRequest req = (HttpServletRequest) request;
        String path = req.getServletPath();
        path = urlRexSub(path);
        perms[0] = path;
        return perms;
    }


    /**
     * 截取却子字符串
     *
     * @return 处理后的字符串
     */
    private static String urlRexSub(String url) {
        int flag = 0;
        String lastUrl = null;
        if (url != null && url.length() > 0) {
            //进行url是否是xxx?id=123类型的url处理
            if (url.contains("?")) {
                int index = url.indexOf("?");
                lastUrl = url.substring(0, index);
                return lastUrl;
            }
            //进行url是xx/xx/{参数}/的URL类型处理
            for (int i = 0; i < url.length(); i++) {
                if (url.charAt(i) == '/') {
                    flag++;
                }
                if (flag == 3) {
                    lastUrl = url.substring(0, i);
                    break;
                }
            }
            if (flag == 3) {
                return lastUrl;
            }
        }
        return url;
    }
}
